<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

namespace App\Services\Impl;

use App\Common\Constant\Params;
use App\Models\Master;
use App\Models\MasterDetail;
use App\Models\MasterStatistic;
use App\Models\MasterWallet;
use App\Notifications\OrderNotification;
use App\Notifications\SystemNotification;
use App\Services\IAreaService;
use App\Services\IMasterService;
use App\Services\IOrderService;
use App\Services\ISessionService;
use App\Services\IStorageService;
use App\Services\ISystemService;
use App\Services\IWeixinService;
use DB;
use Illuminate\Support\Collection;
use Log;

/**
 * Description of UserServiceImpl
 *
 * @author ownfi
 */
class MasterServiceImpl implements IMasterService{

    private $sessionService;
    private $weixinService;
    private $storageService;
    private $orderService;
    private $areaService;

    public function __construct(ISessionService $sessionService, IWeixinService $weixinService,IStorageService $storageService,
                                IOrderService $orderService,IAreaService $areaService)
    {
        $this->sessionService = $sessionService;
        $this->weixinService = $weixinService;
        $this->storageService = $storageService;
        $this->orderService = $orderService;
        $this->areaService = $areaService;
    }

    public function getUserByUserid($userid)
    {
        return Master::find($userid);
    }

    /**
     * 根据微信userid获取用户记录
     * @param type $weixinUserid
     */
    public function getUserByWeixinUserid($weixinUserid){
        return Master::where(['weixin_userid'=>$weixinUserid])->first();
    }

    public function getDetailByUserid($userid)
    {
        return MasterDetail::firstOrCreate(['master_id'=>$userid]);
    }

    public function add($weixinUserId,$phoneNum,$realName,$idcardNum,$baseAreaId,array $serviceAreaIds,$serviceCategory,array $serviceTypes,$idcardFront,$idcardBack,$idcardHold){
        //防止重复注册
        if ($weixinUserId){
            $master = Master::where('weixin_userid',$weixinUserId)->first();
        }else{
            $master = Master::where('phone',$phoneNum)->first();
        }
        if ($master){
            Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'master already exists'));
            return false;
        }

        list($idcardFront,$idcardBack,$idcardHold) = $this->weixinService->getMedia([$idcardFront,$idcardBack,$idcardHold]);

        $master = Master::create([
            'weixin_userid' => $weixinUserId,
            'phone' => $phoneNum,
            'real_name' => $realName,
            'idcard' => $idcardNum,
            'area_id' => $baseAreaId,
            'area_text' => $this->areaService->getAreaCrumbById($baseAreaId),
            'service_area_ids' => $serviceAreaIds,
            'service_category' => $serviceCategory,
            'service_type' => $serviceTypes,
            'idcard_front' => $idcardFront ? ($this->storageService->saveStream($idcardFront) ?: '') : '',
            'idcard_back' => $idcardBack ? ($this->storageService->saveStream($idcardBack) ?: '') : '',
            'idcard_hold' => $idcardHold ? ($this->storageService->saveStream($idcardHold) ?: '') : '',
            'status' => Params::USER_STATUS_REVIEW
        ]);
        if (!$master){
            Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'master create fail'));
            return false;
        }
        $ret = MasterDetail::create([
            'master_id' => $master->id
        ])
        && MasterWallet::create([
            'master_id' => $master->id
        ])
        && MasterStatistic::create([
            'master_id' => $master->id
        ]);
        if (!$master){
            Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'master info create fail'));
            return false;
        }

        return $master;
    }

    public function updateWeinxinUserid($masterId, $weixinUserid)
    {
        $model = Master::find($masterId);
        if ($model){
            $model->weixin_userid = $weixinUserid;

            $weixinOpenid = $this->weixinService->useridToOpenid($weixinUserid);
            if ($weixinOpenid){
                $model->weixin_openid = $weixinOpenid;
            }

            return $model->save();
        }

        return false;
    }

    public function phoneExists($phone)
    {
        return (bool)Master::where('phone',$phone)->count();
    }

    public function changePhone($master_id, $phone)
    {
        return Master::find($master_id)->update([
            'phone' => $phone
        ]);
    }

    public function changeArea($master_id, $areaId)
    {
        return Master::find($master_id)->update([
            'area_id' => $areaId,
            'area_text' => $this->areaService->getAreaCrumbById($areaId),
            'service_area_ids'=> []
        ]);
    }

    public function changeServiceType($master_id, array $serviceType)
    {
        return Master::find($master_id)->update([
            'service_type' => $serviceType
        ]);
    }

    public function changeServiceAreaIds($master_id, array $serviceAreaIds)
    {
        return Master::find($master_id)->update([
            'service_area_ids' => $serviceAreaIds
        ]);
    }

    public function changeServiceExtra($master_id, $extra_finish_in, $extra_nothing_fee, $extra_repair_free, $extra_floor_free,
                                       $extra_carry_fee, $extra_far_fee, $extra_tmall_examine, $extra_storage, $extra_move_free)
    {
        return MasterDetail::where(['master_id'=>$master_id])->take(1)->update([
            'extra_finish_in' => $extra_finish_in,
            'extra_nothing_fee' => $extra_nothing_fee,
            'extra_repair_free' => $extra_repair_free,
            'extra_floor_free' => $extra_floor_free,
            'extra_carry_fee' => $extra_carry_fee,
            'extra_far_fee' => $extra_far_fee,
            'extra_tmall_examine' => $extra_tmall_examine,
            'extra_storage' => $extra_storage,
            'extra_move_free' => $extra_move_free,
        ]);
    }

    public function intendChangeHeadimg($master_id, $head_img)
    {
        $model = MasterDetail::where('master_id',$master_id)->first();
        if (!$model){
            Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'miss master detail'));
            return false;
        }
        list($head_img) = $this->weixinService->getMedia([$head_img]);
        $model->head_chang_to = $this->storageService->saveStream($head_img);
        return $model->save();
    }

    public function updateDetail($master_id,array $updates)
    {
        $model = MasterDetail::where('master_id',$master_id)->first();
        if (!$model){
            Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'miss master detail'));
            return false;
        }
        foreach ($updates as $field=>$value){
            $model->$field = $value;
        }
        return $model->save();
    }

    public function transformMerchantServiceType($merchant_service_type)
    {
        $master_service_type = [];
        Collection::make((array)$merchant_service_type)->each(function($item, $key) use(&$master_service_type){
            $transform = [
                Params::MERCHANT_SERVICE_TYPE_DELIVERY_INSTALL=>[Params::SERVICE_TYPE_DELIVERY,Params::SERVICE_TYPE_INSTALL],
                Params::MERCHANT_SERVICE_TYPE_INSTALL=>[Params::SERVICE_TYPE_INSTALL],
                Params::MERCHANT_SERVICE_TYPE_REPAIR=>[Params::SERVICE_TYPE_REPAIR],
                Params::MERCHANT_SERVICE_TYPE_DELIVERY=>[Params::SERVICE_TYPE_DELIVERY],
                Params::MERCHANT_SERVICE_TYPE_PACK_RETURN=>[Params::SERVICE_TYPE_DELIVERY],
            ];
            $master_service_type = array_merge($master_service_type,$transform[$item]);
        });
        sort($master_service_type);
        return array_unique($master_service_type);
    }

    public function getMessageCount($master_id)
    {
        $unreadNotifications = Master::find($master_id)->unreadNotifications;

        $system_message_count = $unreadNotifications->filter(function($item, $key){
            return starts_with($item->type,SystemNotification::class);
        })->count();
        $order_message_count = $unreadNotifications->filter(function($item, $key){
            return starts_with($item->type,OrderNotification::class);
        })->count();
        return [$system_message_count,$order_message_count];
    }

    public function listSystemMessage($master_id)
    {
        $notifications = Master::find($master_id)->notifications;
        return $notifications->filter(function($item, $key){
            return starts_with($item->type,SystemNotification::class);
        });
    }

    public function listOrderMessage($master_id)
    {
        $notifications = Master::find($master_id)->notifications;
        return $notifications->filter(function($item, $key){
            return starts_with($item->type,OrderNotification::class);
        });
    }

}
